{
    "cells": [
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "<i>Copyright (c) Recommenders contributors.</i>\n",
                "\n",
                "<i>Licensed under the MIT License.</i>"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "# Data transformation (collaborative filtering)"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "It is usually observed in the real-world datasets that users may have different types of interactions with items. In addition, same types of interactions (e.g., click an item on the website, view a movie, etc.) may also appear more than once in the history. Given that this is a typical problem in practical recommendation system design, the notebook shares data transformation techniques that can be used for different scenarios.\n",
                "\n",
                "Specifically, the discussion in this notebook is only applicable to collaborative filtering algorithms."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## 0 Global settings"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 1,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "System version: 3.9.16 (main, May 15 2023, 23:46:34) \n",
                        "[GCC 11.2.0]\n",
                        "NumPy version: 1.24.3\n",
                        "Pandas version: 1.5.3\n"
                    ]
                }
            ],
            "source": [
                "import sys\n",
                "import pandas as pd\n",
                "import numpy as np\n",
                "import datetime\n",
                "import math\n",
                "\n",
                "print(f\"System version: {sys.version}\")\n",
                "print(f\"NumPy version: {np.__version__}\")\n",
                "print(f\"Pandas version: {pd.__version__}\")"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## 1 Data creation"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Two dummy datasets are created to illustrate the ideas in the notebook. "
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### 1.1 Explicit feedback\n",
                "\n",
                "In the \"explicit feedback\" scenario, interactions between users and items are numerical / ordinal **ratings** or binary preferences such as **like** or **dislike**. These types of interactions are termed as *explicit feedback*.\n",
                "\n",
                "The following shows a dummy data for the explicit rating type of feedback. In the data,\n",
                "* There are 3 users whose IDs are 1, 2, 3.\n",
                "* There are 3 items whose IDs are 1, 2, 3.\n",
                "* Items are rated by users only once. So even when users interact with items at different timestamps, the ratings are kept the same. This is seen in some use cases such as movie recommendations, where users' ratings do not change dramatically over a short period of time.\n",
                "* Timestamps of when the ratings are given are also recorded."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 2,
            "metadata": {},
            "outputs": [],
            "source": [
                "data1 = pd.DataFrame({\n",
                "    \"UserId\": [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3],\n",
                "    \"ItemId\": [1, 1, 2, 2, 2, 1, 2, 1, 2, 3, 3, 3, 3, 3, 1],\n",
                "    \"Rating\": [4, 4, 3, 3, 3, 4, 5, 4, 5, 5, 5, 5, 5, 5, 4],\n",
                "    \"Timestamp\": [\n",
                "        '2000-01-01', '2000-01-01', '2000-01-02', '2000-01-02', '2000-01-02',\n",
                "        '2000-01-01', '2000-01-01', '2000-01-03', '2000-01-03', '2000-01-03',\n",
                "        '2000-01-01', '2000-01-03', '2000-01-03', '2000-01-03', '2000-01-04'\n",
                "    ]\n",
                "})"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 3,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Rating</th>\n",
                            "      <th>Timestamp</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>9</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>10</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>11</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>12</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>13</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>14</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-04</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "    UserId  ItemId  Rating   Timestamp\n",
                            "0        1       1       4  2000-01-01\n",
                            "1        1       1       4  2000-01-01\n",
                            "2        1       2       3  2000-01-02\n",
                            "3        1       2       3  2000-01-02\n",
                            "4        1       2       3  2000-01-02\n",
                            "5        2       1       4  2000-01-01\n",
                            "6        2       2       5  2000-01-01\n",
                            "7        2       1       4  2000-01-03\n",
                            "8        2       2       5  2000-01-03\n",
                            "9        2       3       5  2000-01-03\n",
                            "10       3       3       5  2000-01-01\n",
                            "11       3       3       5  2000-01-03\n",
                            "12       3       3       5  2000-01-03\n",
                            "13       3       3       5  2000-01-03\n",
                            "14       3       1       4  2000-01-04"
                        ]
                    },
                    "execution_count": 3,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data1"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### 1.2 Implicit feedback\n",
                "\n",
                "Many times there are no explicit ratings or preferences given by users, that is, the interactions are usually implicit. For example, a user may puchase something on a website, click an item on a mobile app, or order food from a restaurant. This information may reflect users' preference towards the items in an **implicit** manner. \n",
                "\n",
                "As follows, a data set is created to illustrate the implicit feedback scenario. \n",
                "\n",
                "In the data,\n",
                "* There are 3 users whose IDs are 1, 2, 3.\n",
                "* There are 3 items whose IDs are 1, 2, 3.\n",
                "* There are no ratings or explicit feedback given by the users. Sometimes there are the types of events. In this dummy dataset, for illustration purposes, there are three types for the interactions between users and items, that is, **click**, **add** and **purchase**, meaning \"click on the item\", \"add the item into cart\" and \"purchase the item\", respectively. \n",
                "* Sometimes there is other contextual or associative information available for the types of interactions. E.g., \"time-spent on visiting a site before clicking\" etc. For simplicity, only the type of interactions is considered in this notebook.\n",
                "* The timestamp of each interaction is also given."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 4,
            "metadata": {},
            "outputs": [],
            "source": [
                "data2 = pd.DataFrame({\n",
                "    \"UserId\": [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3],\n",
                "    \"ItemId\": [1, 1, 2, 2, 2, 1, 2, 1, 2, 3, 3, 3, 3, 3, 1],\n",
                "    \"Type\": [\n",
                "        'click', 'click', 'click', 'click', 'purchase',\n",
                "        'click', 'purchase', 'add', 'purchase', 'purchase',\n",
                "        'click', 'click', 'add', 'purchase', 'click'\n",
                "    ],\n",
                "    \"Timestamp\": [\n",
                "        '2000-01-01', '2000-01-01', '2000-01-02', '2000-01-02', '2000-01-02',\n",
                "        '2000-01-01', '2000-01-01', '2000-01-03', '2000-01-03', '2000-01-03',\n",
                "        '2000-01-01', '2000-01-03', '2000-01-03', '2000-01-03', '2000-01-04'\n",
                "    ]\n",
                "})"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 5,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>Timestamp</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>add</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>9</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>10</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>11</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>12</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>add</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>13</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>14</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-04</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "    UserId  ItemId      Type   Timestamp\n",
                            "0        1       1     click  2000-01-01\n",
                            "1        1       1     click  2000-01-01\n",
                            "2        1       2     click  2000-01-02\n",
                            "3        1       2     click  2000-01-02\n",
                            "4        1       2  purchase  2000-01-02\n",
                            "5        2       1     click  2000-01-01\n",
                            "6        2       2  purchase  2000-01-01\n",
                            "7        2       1       add  2000-01-03\n",
                            "8        2       2  purchase  2000-01-03\n",
                            "9        2       3  purchase  2000-01-03\n",
                            "10       3       3     click  2000-01-01\n",
                            "11       3       3     click  2000-01-03\n",
                            "12       3       3       add  2000-01-03\n",
                            "13       3       3  purchase  2000-01-03\n",
                            "14       3       1     click  2000-01-04"
                        ]
                    },
                    "execution_count": 5,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data2"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## 2 Data transformation"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Many collaborative filtering algorithms are built on a user-item sparse matrix. This requires that the input data for building the recommender should contain unique user-item pairs. \n",
                "\n",
                "For explicit feedback datasets, this can simply be done by deduplicating the repeated user-item-rating tuples."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 6,
            "metadata": {},
            "outputs": [],
            "source": [
                "data1 = data1.drop_duplicates()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 7,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Rating</th>\n",
                            "      <th>Timestamp</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>9</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>10</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>11</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>14</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>4</td>\n",
                            "      <td>2000-01-04</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "    UserId  ItemId  Rating   Timestamp\n",
                            "0        1       1       4  2000-01-01\n",
                            "2        1       2       3  2000-01-02\n",
                            "5        2       1       4  2000-01-01\n",
                            "6        2       2       5  2000-01-01\n",
                            "7        2       1       4  2000-01-03\n",
                            "8        2       2       5  2000-01-03\n",
                            "9        2       3       5  2000-01-03\n",
                            "10       3       3       5  2000-01-01\n",
                            "11       3       3       5  2000-01-03\n",
                            "14       3       1       4  2000-01-04"
                        ]
                    },
                    "execution_count": 7,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data1"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "In the implicit feedback use cases, there are several methods to perform the deduplication, depending on the requirements of the actual business user cases."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### 2.1 Data aggregation\n",
                "\n",
                "Usually, data is aggregated by user to generate some scores that represent preferences (in some algorithms like SAR, the score is called *affinity score*, for simplicity reason, hereafter the scores are termed as *affinity*).\n",
                "\n",
                "It is worth mentioning that in such case, the affinity scores are different from the ratings in the explicit data set, in terms of value distribution. This is usually termed as an [ordinal regression](https://en.wikipedia.org/wiki/Ordinal_regression) problem, which has been studied in [Koren's paper](https://pdfs.semanticscholar.org/934a/729409d6fbd9894a94d4af66bd82222b5515.pdf). In this case, the algorithm used for training a recommender should be carefully chosen to consider the distribution of the affinity scores rather than discrete integer values."
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### 2.2.1 Count\n",
                "\n",
                "The most simple technique is to count times of interactions between user and item for producing affinity scores. The following shows the aggregation of counts of user-item interactions in `data2` regardless the interaction type."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 8,
            "metadata": {},
            "outputs": [],
            "source": [
                "data2_count = data2.groupby(['UserId', 'ItemId']).agg({'Timestamp': 'count'}).reset_index()\n",
                "data2_count.columns = ['UserId', 'ItemId', 'Affinity']"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 9,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Affinity</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>4</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "   UserId  ItemId  Affinity\n",
                            "0       1       1         2\n",
                            "1       1       2         3\n",
                            "2       2       1         2\n",
                            "3       2       2         2\n",
                            "4       2       3         1\n",
                            "5       3       1         1\n",
                            "6       3       3         4"
                        ]
                    },
                    "execution_count": 9,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data2_count"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### 2.2.1 Weighted count"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "It is useful to consider the types of different interactions as weights in the count aggregation. For example, assuming weights of the three differen types, \"click\", \"add\", and \"purchase\", are 1, 2, and 3, respectively. A weighted-count can be done as the following"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 10,
            "metadata": {},
            "outputs": [],
            "source": [
                "# Add column of weights\n",
                "data2_w = data2.copy()\n",
                "\n",
                "conditions = [\n",
                "    data2_w['Type'] == 'click',\n",
                "    data2_w['Type'] == 'add',\n",
                "    data2_w['Type'] == 'purchase'\n",
                "]\n",
                "\n",
                "choices = [1, 2, 3]\n",
                "\n",
                "data2_w['Weight'] = np.select(conditions, choices, default='black')\n",
                "\n",
                "# Convert to numeric type.\n",
                "data2_w['Weight'] = pd.to_numeric(data2_w['Weight'])"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 11,
            "metadata": {},
            "outputs": [],
            "source": [
                "# Do count with weight.\n",
                "data2_wcount = data2_w.groupby(['UserId', 'ItemId'])['Weight'].sum().reset_index()\n",
                "data2_wcount.columns = ['UserId', 'ItemId', 'Affinity']"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 12,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Affinity</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>5</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>3</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>6</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>7</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "   UserId  ItemId  Affinity\n",
                            "0       1       1         2\n",
                            "1       1       2         5\n",
                            "2       2       1         3\n",
                            "3       2       2         6\n",
                            "4       2       3         3\n",
                            "5       3       1         1\n",
                            "6       3       3         7"
                        ]
                    },
                    "execution_count": 12,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data2_wcount"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### 2.2.2 Time dependent count"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "In many scenarios, time dependency plays a critical role in preparing dataset for building a collaborative filtering model that captures user interests drift over time. One of the common techniques for achieving time dependent count is to add a time decay factor in the counting. This technique is used in [SAR](https://github.com/microsoft/recommenders/blob/main/examples/02_model_collaborative_filtering/sar_deep_dive.ipynb). Formula for getting affinity score for each user-item pair is \n",
                "\n",
                "$$a_{ij}=\\sum_k w_k \\left(\\frac{1}{2}\\right)^{\\frac{t_0-t_k}{T}} $$\n",
                "\n",
                "where $a_{ij}$ is the affinity score, $w_k$ is the interaction weight, $t_0$ is a reference time, $t_k$ is the timestamp for the $k$-th interaction, and $T$ is a hyperparameter that controls the speed of decay.\n",
                "\n",
                "The following shows how SAR applies time decay in aggregating counts for the implicit feedback scenario. "
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "In this case, we use 5 days as the half-life parameter, and use the latest time in the dataset as the time reference."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 13,
            "metadata": {},
            "outputs": [],
            "source": [
                "T = 5\n",
                "\n",
                "t_ref = pd.to_datetime(data2_w['Timestamp']).max()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 14,
            "metadata": {},
            "outputs": [],
            "source": [
                "# Calculate the weighted count with time decay.\n",
                "\n",
                "data2_w['Timedecay'] = data2_w.apply(\n",
                "    lambda x: x['Weight'] * np.power(0.5, (t_ref - pd.to_datetime(x['Timestamp'])).days / T), \n",
                "    axis=1\n",
                ")"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 15,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Type</th>\n",
                            "      <th>Timestamp</th>\n",
                            "      <th>Weight</th>\n",
                            "      <th>Timedecay</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0.659754</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0.659754</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0.757858</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0.757858</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-02</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2.273575</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0.659754</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "      <td>3</td>\n",
                            "      <td>1.979262</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>add</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "      <td>2</td>\n",
                            "      <td>1.741101</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2.611652</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>9</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2.611652</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>10</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-01</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0.659754</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>11</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0.870551</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>12</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>add</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "      <td>2</td>\n",
                            "      <td>1.741101</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>13</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>purchase</td>\n",
                            "      <td>2000-01-03</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2.611652</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>14</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>click</td>\n",
                            "      <td>2000-01-04</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1.000000</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "    UserId  ItemId      Type   Timestamp  Weight  Timedecay\n",
                            "0        1       1     click  2000-01-01       1   0.659754\n",
                            "1        1       1     click  2000-01-01       1   0.659754\n",
                            "2        1       2     click  2000-01-02       1   0.757858\n",
                            "3        1       2     click  2000-01-02       1   0.757858\n",
                            "4        1       2  purchase  2000-01-02       3   2.273575\n",
                            "5        2       1     click  2000-01-01       1   0.659754\n",
                            "6        2       2  purchase  2000-01-01       3   1.979262\n",
                            "7        2       1       add  2000-01-03       2   1.741101\n",
                            "8        2       2  purchase  2000-01-03       3   2.611652\n",
                            "9        2       3  purchase  2000-01-03       3   2.611652\n",
                            "10       3       3     click  2000-01-01       1   0.659754\n",
                            "11       3       3     click  2000-01-03       1   0.870551\n",
                            "12       3       3       add  2000-01-03       2   1.741101\n",
                            "13       3       3  purchase  2000-01-03       3   2.611652\n",
                            "14       3       1     click  2000-01-04       1   1.000000"
                        ]
                    },
                    "execution_count": 15,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data2_w"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Affinity scores of user-item pairs can be calculated then by summing the 'Timedecay' column values."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 16,
            "metadata": {},
            "outputs": [],
            "source": [
                "data2_wt = data2_w.groupby(['UserId', 'ItemId'])['Timedecay'].sum().reset_index()\n",
                "data2_wt.columns = ['UserId', 'ItemId', 'Affinity']"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 17,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Affinity</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1.319508</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>3.789291</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>2.400855</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>4.590914</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>2.611652</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1.000000</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>5.883057</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "   UserId  ItemId  Affinity\n",
                            "0       1       1  1.319508\n",
                            "1       1       2  3.789291\n",
                            "2       2       1  2.400855\n",
                            "3       2       2  4.590914\n",
                            "4       2       3  2.611652\n",
                            "5       3       1  1.000000\n",
                            "6       3       3  5.883057"
                        ]
                    },
                    "execution_count": 17,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data2_wt"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### 2.2 Negative sampling"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "The above aggregation is based on assumptions that user-item interactions can be interpreted as preferences by taking the factors like \"number of interation times\", \"weights\", \"time decay\", etc. Sometimes these assumptions are biased, and only the interactions themselves matter. That is, the original dataset with implicit interaction records can be binarized into one that has only 1 or 0, indicating if a user has interacted with an item, respectively.\n",
                "\n",
                "For example, the following generates data that contains existing interactions between users and items. "
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 18,
            "metadata": {},
            "outputs": [],
            "source": [
                "data2_b = data2[['UserId', 'ItemId']].copy()\n",
                "data2_b['Feedback'] = 1\n",
                "data2_b = data2_b.drop_duplicates()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 19,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Feedback</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>9</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>10</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>14</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "    UserId  ItemId  Feedback\n",
                            "0        1       1         1\n",
                            "2        1       2         1\n",
                            "5        2       1         1\n",
                            "6        2       2         1\n",
                            "9        2       3         1\n",
                            "10       3       3         1\n",
                            "14       3       1         1"
                        ]
                    },
                    "execution_count": 19,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data2_b"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "\"Negative sampling\" is a technique that samples negative feedback. Similar to the aggregation techniques, negative feedback cna be defined differently in different scenarios. In this case, for example, we can regard the items that a user has not interacted as those that the user does not like. This may be a strong assumption in many user cases, but it is reasonable to build a model when the interaction times between user and item are not that many.\n",
                "\n",
                "The following shows that, on top of `data2_b`, there are another 2 negative samples are generated which are tagged with \"0\" in the \"Feedback\" column."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 20,
            "metadata": {},
            "outputs": [],
            "source": [
                "users = data2['UserId'].unique()\n",
                "items = data2['ItemId'].unique()"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 21,
            "metadata": {},
            "outputs": [],
            "source": [
                "interaction_lst = []\n",
                "for user in users:\n",
                "    for item in items:\n",
                "        interaction_lst.append([user, item, 0])\n",
                "\n",
                "data_all = pd.DataFrame(data=interaction_lst, columns=[\"UserId\", \"ItemId\", \"FeedbackAll\"])"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 22,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>FeedbackAll</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>1</td>\n",
                            "      <td>3</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>3</td>\n",
                            "      <td>2</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "   UserId  ItemId  FeedbackAll\n",
                            "0       1       1            0\n",
                            "1       1       2            0\n",
                            "2       1       3            0\n",
                            "3       2       1            0\n",
                            "4       2       2            0\n",
                            "5       2       3            0\n",
                            "6       3       1            0\n",
                            "7       3       2            0\n",
                            "8       3       3            0"
                        ]
                    },
                    "execution_count": 22,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data_all"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 23,
            "metadata": {},
            "outputs": [],
            "source": [
                "data2_ns = pd.merge(data_all, data2_b, on=['UserId', 'ItemId'], how='outer').fillna(0).drop('FeedbackAll', axis=1)"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 24,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "text/html": [
                            "<div>\n",
                            "<style scoped>\n",
                            "    .dataframe tbody tr th:only-of-type {\n",
                            "        vertical-align: middle;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe tbody tr th {\n",
                            "        vertical-align: top;\n",
                            "    }\n",
                            "\n",
                            "    .dataframe thead th {\n",
                            "        text-align: right;\n",
                            "    }\n",
                            "</style>\n",
                            "<table border=\"1\" class=\"dataframe\">\n",
                            "  <thead>\n",
                            "    <tr style=\"text-align: right;\">\n",
                            "      <th></th>\n",
                            "      <th>UserId</th>\n",
                            "      <th>ItemId</th>\n",
                            "      <th>Feedback</th>\n",
                            "    </tr>\n",
                            "  </thead>\n",
                            "  <tbody>\n",
                            "    <tr>\n",
                            "      <th>0</th>\n",
                            "      <td>1</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>1</th>\n",
                            "      <td>1</td>\n",
                            "      <td>2</td>\n",
                            "      <td>1.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>2</th>\n",
                            "      <td>1</td>\n",
                            "      <td>3</td>\n",
                            "      <td>0.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>3</th>\n",
                            "      <td>2</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>4</th>\n",
                            "      <td>2</td>\n",
                            "      <td>2</td>\n",
                            "      <td>1.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>5</th>\n",
                            "      <td>2</td>\n",
                            "      <td>3</td>\n",
                            "      <td>1.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>6</th>\n",
                            "      <td>3</td>\n",
                            "      <td>1</td>\n",
                            "      <td>1.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>7</th>\n",
                            "      <td>3</td>\n",
                            "      <td>2</td>\n",
                            "      <td>0.0</td>\n",
                            "    </tr>\n",
                            "    <tr>\n",
                            "      <th>8</th>\n",
                            "      <td>3</td>\n",
                            "      <td>3</td>\n",
                            "      <td>1.0</td>\n",
                            "    </tr>\n",
                            "  </tbody>\n",
                            "</table>\n",
                            "</div>"
                        ],
                        "text/plain": [
                            "   UserId  ItemId  Feedback\n",
                            "0       1       1       1.0\n",
                            "1       1       2       1.0\n",
                            "2       1       3       0.0\n",
                            "3       2       1       1.0\n",
                            "4       2       2       1.0\n",
                            "5       2       3       1.0\n",
                            "6       3       1       1.0\n",
                            "7       3       2       0.0\n",
                            "8       3       3       1.0"
                        ]
                    },
                    "execution_count": 24,
                    "metadata": {},
                    "output_type": "execute_result"
                }
            ],
            "source": [
                "data2_ns"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Also note that sometimes the negative sampling may also impact the count-based aggregation scheme. That is, the count may start from 0 instead of 1, and 0 means there is no interaction between the user and item. "
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "# References\n",
                "\n",
                "1. X. He *et al*, Neural Collaborative Filtering, WWW 2017. \n",
                "2. Y. Hu *et al*, Collaborative filtering for implicit feedback datasets, ICDM 2008.\n",
                "3. Simple Algorithm for Recommendation (SAR). See notebook [sar_deep_dive.ipynb](../02_model_collaborative_filtering/sar_deep_dive.ipynb).\n",
                "4. Y. Koren and J. Sill, OrdRec: an ordinal model for predicting personalized item rating distributions, RecSys 2011."
            ]
        }
    ],
    "metadata": {
        "kernelspec": {
            "display_name": "Python (recommenders)",
            "language": "python",
            "name": "recommenders"
        },
        "language_info": {
            "codemirror_mode": {
                "name": "ipython",
                "version": 3
            },
            "file_extension": ".py",
            "mimetype": "text/x-python",
            "name": "python",
            "nbconvert_exporter": "python",
            "pygments_lexer": "ipython3",
            "version": "3.9.16"
        }
    },
    "nbformat": 4,
    "nbformat_minor": 2
}